package edu.zju.gis.dbfg.queryserver.service.impl;

import edu.zju.gis.dbfg.queryserver.model.SearchResult;
import edu.zju.gis.dbfg.queryserver.service.AttributeQueryService;
import edu.zju.gis.dbfg.queryserver.tool.FormatUtil;
import edu.zju.gis.dbfg.queryserver.tool.RestElasticSearchHelper;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static edu.zju.gis.dbfg.queryserver.constant.LimitedFieldsName.NO_SCROLL;

@Slf4j
@Service
public class AttributeQueryServiceImp implements AttributeQueryService {

    @Autowired
    private RestElasticSearchHelper helper;

    public long selectTotalSize(String indexName) {
        return helper.selectTotalSize(indexName);
    }

    public SearchResult selectByFromSize(String indexName, int from, int size) {
        SearchRequest searchRequest = BuildSearchRequest(indexName, from, size);
        return FormatUtil.SearchResponse2Result(helper.search(searchRequest));
    }

    public SearchResult selectByScroll(String indexName, String scrollId, int size) {
        if (scrollId.equals(NO_SCROLL)) {
            SearchRequest searchRequest = BuildSearchRequest(indexName, 0, size);
            searchRequest.scroll("5m");
            return FormatUtil.SearchResponse2Result(helper.search(searchRequest));
        }
        SearchScrollRequest request = new SearchScrollRequest();
        request.scroll("5m");
        request.scrollId(scrollId);
        return FormatUtil.SearchResponse2Result(helper.scroll(request));
    }

    public SearchResult selectByDocId(String indexName, String id) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        IdsQueryBuilder idQb = QueryBuilders.idsQuery();
        idQb.addIds(id);
        searchSourceBuilder.query(idQb);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(indexName);
        searchRequest.source(searchSourceBuilder);
        return FormatUtil.SearchResponse2Result(helper.search(searchRequest));
    }

    public SearchResult selectByField(String indexName, String fieldName, String value) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //TODO match fuzzy matchPhraseQuery区分功能与效率
        searchSourceBuilder.query(QueryBuilders.matchPhraseQuery(fieldName, value));
        //TODO 属性查询可获取全部匹配条数 or 100条
        searchSourceBuilder.size(100);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(indexName);
        searchRequest.source(searchSourceBuilder);
        return FormatUtil.SearchResponse2Result(helper.search(searchRequest));
    }

    private SearchRequest BuildSearchRequest(String indexName, int from, int size) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(indexName);
        searchRequest.source(searchSourceBuilder);
        return searchRequest;
    }
}
